﻿using System;
using System.Xml;

namespace RemoteTestRunner.BusinessLogic
{

    #region Enumerated Types

    /// <summary>
    ///   Specifies a connection string setting.
    /// </summary>
    public enum ConnectionStringSetting
    {
        /// <summary>
        ///   The application name.
        /// </summary>
        ApplicationName,

        /// <summary>
        ///   The connection timeout value.
        /// </summary>
        ConnectionTimeout,

        /// <summary>
        ///   The current language.
        /// </summary>
        CurrentLanguage,

        /// <summary>
        ///   The database name.
        /// </summary>
        Database,

        /// <summary>
        ///   The data source.
        /// </summary>
        DataSource,

        /// <summary>
        ///   The encryption setting.
        /// </summary>
        Encrypt,

        /// <summary>
        ///   The Integrated Security (SSPI) setting.
        /// </summary>
        IntegratedSecurity,

        /// <summary>
        ///   The server instance.
        /// </summary>
        Instance,

        /// <summary>
        ///   The packet size.
        /// </summary>
        PacketSize,

        /// <summary>
        ///   The database password.
        /// </summary>
        Password,

        /// <summary>
        ///   The persist security information setting.
        /// </summary>
        PersistSecurityInfo,

        /// <summary>
        ///   The database server.
        /// </summary>
        Server,

        /// <summary>
        ///   The database server and instance combined.
        /// </summary>
        ServerAndInstance,

        /// <summary>
        ///   The database logon ID.
        /// </summary>
        UserId,

        /// <summary>
        ///   The workstation ID.
        /// </summary>
        WorkstationId
    }

    #endregion

    public class Utilities
    {
        /// <summary>
        ///   Returns a specific setting within a SQL Server connection string.
        /// </summary>
        /// <param name = "connectionString">The connection string to parse.</param>
        /// <param name = "setting">The name of the setting to return.</param>
        /// <returns>Returns a String value for the specified connection string setting.  An 
        ///   empty string is returned if the setting is not present.</returns>
        public static string GetConnectionStringSetting(string connectionString, ConnectionStringSetting setting)
        {
            string[] settings;
            string[] settingsKeys;
            string csSetting = string.Empty;
            string settingKey = string.Empty;
            int position;

            if (connectionString != null)
            {
                switch (setting)
                {
                    case ConnectionStringSetting.ApplicationName:
                        settingKey = "application name";
                        break;
                    case ConnectionStringSetting.ConnectionTimeout:
                        settingKey = "connect timeout;connection timeout";
                        break;
                    case ConnectionStringSetting.CurrentLanguage:
                        settingKey = "current language";
                        break;
                    case ConnectionStringSetting.Database:
                        settingKey = "initial catalog;database";
                        break;
                    case ConnectionStringSetting.Encrypt:
                        settingKey = "encrypt";
                        break;
                    case ConnectionStringSetting.IntegratedSecurity:
                        settingKey = "integrated security;trusted_connection";
                        break;
                    case ConnectionStringSetting.PacketSize:
                        settingKey = "packet size";
                        break;
                    case ConnectionStringSetting.Password:
                        settingKey = "password;pwd";
                        break;
                    case ConnectionStringSetting.PersistSecurityInfo:
                        settingKey = "persist security info";
                        break;
                    case ConnectionStringSetting.DataSource:
                    case ConnectionStringSetting.Server:
                    case ConnectionStringSetting.Instance:
                    case ConnectionStringSetting.ServerAndInstance:
                        settingKey = "data source;server;address;network address";
                        break;
                    case ConnectionStringSetting.UserId:
                        settingKey = "user id";
                        break;
                    case ConnectionStringSetting.WorkstationId:
                        settingKey = "workstation id";
                        break;
                }

                settings = connectionString.Split(';');

                for (int index = 0; index <= (settings.Length - 1); index++)
                {
                    settingsKeys = settingKey.Split(';');

                    for (int keyIndex = 0; keyIndex <= (settingsKeys.Length - 1); keyIndex++)
                    {
                        if (settings[index].Trim().ToLower().IndexOf(settingsKeys[keyIndex]) >= 0)
                        {
                            csSetting = settings[index].Substring(settings[index].IndexOf("=") + 1);

                            break;
                        }
                    }

                    if (csSetting.Length > 0)
                    {
                        break;
                    }
                }
            }

            if (setting == ConnectionStringSetting.Server)
            {
                // Remove the instance name from the server/instance setting if one exists
                position = csSetting.IndexOf("\\");

                if (position > 0)
                {
                    csSetting = csSetting.Substring(0, position);
                }
            }
            else if (setting == ConnectionStringSetting.Instance)
            {
                // Remove the server name from the server/instance setting if one exists
                position = csSetting.IndexOf("\\");

                if ((position > 0) && ((position + 1) < csSetting.Length))
                {
                    csSetting = csSetting.Substring(position + 1);
                }
            }

            return csSetting;
        }

        /// <summary>
        ///   Gets the specified attribute value from the attribute collection.
        /// </summary>
        /// <param name = "attributes">The collection of attributes to search.</param>
        /// <param name = "name">The name of the attribute value to retrieve.</param>
        /// <returns>If found, the value of the specified attribute; otherwise, and empty string
        ///   is returned.</returns>
        public static string GetAttributeValue(XmlAttributeCollection attributes, string name)
        {
            return GetAttributeValue(attributes, name, string.Empty);
        }

        /// <summary>
        ///   Gets the specified attribute value from the attribute collection.
        /// </summary>
        /// <param name = "attributes">The collection of attributes to search.</param>
        /// <param name = "name">The name of the attribute value to retrieve.</param>
        /// <param name = "defaultValue">The default value to return if the attribute is not located.</param>
        /// <returns>If found, the value of the specified attribute; otherwise, and empty string
        ///   is returned.</returns>
        public static string GetAttributeValue(XmlAttributeCollection attributes, string name, string defaultValue)
        {
            string value = defaultValue;

            foreach (XmlAttribute attribute in attributes)
            {
                if (string.Equals(attribute.Name, name, StringComparison.InvariantCultureIgnoreCase))
                {
                    value = attribute.Value;

                    break;
                }
            }

            return value;
        }
    }
}